local _G = _G

local select = _G.select
local GetTime = _G.GetTime
local CreateFrame = _G.CreateFrame
local WorldFrame = _G.WorldFrame

local MAX_UPDATE_COUNT = 1000
local LOCKUP_TIME = 1.5

local index, offset, events, times, offsets, args

local function newdb()
	index, offset = 1, 1
	events = {}
	times = {}
	offsets = {}
	args = {}
end

local function cleandb()
	for i = index, 1, -1 do
		events[i] = nil
		times[i] = nil
		offsets[i] = nil
	end
	index = 1
	for i = offset, 1, -1 do
		offsets[i] = nil
	end
	offset = 1
end

local function OnEvent(self, event, ...)
	events[index] = event
	times[index] = GetTime()
	offsets[index] = offset
	for i = 1, select("#", ...) do
		args[offset] = select(i, ...)
		offset = offset + 1
	end
	index = index + 1
end

local function FirstOnEvent(self, event, ...)
	_G.ChatFrame1:AddMessage("Recording...")
	newdb()
	self:SetScript("OnEvent", OnEvent)
	OnEvent(self, event, ...)
end

local data = {}
local index = 0
local function Lockup_OnUpdate(frame, elapsed)
	if frame.text then
		index = (index > 10) and 1 or (index + 1)
		data[index] = #events
		local sum = 0
		for i = 1, #data do
			sum = sum + data[i]
		end
		frame.text:SetFormattedText("%d", sum / (elapsed * 10))
	end
	if elapsed > LOCKUP_TIME then
		local db = _G.CheckLockDB
		if not db then
			db = {}
			_G.CheckLockDB = db
		end
		db[#db + 1] = {
			events = events,
			times = times,
			offsets = offsets,
			args = args,
			lockup = elapsed,
		}
		for i = #args, offset, -1 do
			args[i] = nil
		end
		_G.ChatFrame1:AddMessage(("Lockup detected, %d events received during this lockup"):format(#db[#db].events))
		newdb()
	elseif index > 1 then
		cleandb()
	end
end

local function StartUp_OnUpdate(self, ...)
	MAX_UPDATE_COUNT = MAX_UPDATE_COUNT - 1
	if MAX_UPDATE_COUNT < 0 then
		_G.ChatFrame1:AddMessage(("Stopped recording after %d events..."):format(#events))
		-- self:Hide()
		self:SetScript("OnUpdate", Lockup_OnUpdate)
		_G.RecorderDB = {
			events = events,
			times = times,
			offsets = offsets,
			args = args,
		}
		newdb()
	else
		OnEvent(self, "update", ...)
	end
end

local f = CreateFrame("Frame", "RecorderFrame", WorldFrame)
f:SetScript("OnEvent", FirstOnEvent)
f:SetScript("OnUpdate", StartUp_OnUpdate)
f:RegisterAllEvents()
f:Show()
f:SetPoint("CENTER", 0, 350)
f:SetWidth(150)
f:SetHeight(14)
-- f.text = f:CreateFontString(nil, "ARTWORK", "GameFontNormal")
-- f.text:SetAllPoints()
